﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Arduino.Firmata.Types
{
    //public sealed class Types
    //{
    //private Types()
    //{

    //}

    #region Types
    /// <summary>
    /// Перечисление режимов работы портов микроконтроллера Arduino.
    /// </summary>
    public enum PinMode : int
    {
        None = -1,

        Output = 0,
        Input = 1,
        Analog = 2,
        PWM = 3,
        Servo = 4,
        Shift = 5,
        I2C = 6
    }

    /// <summary>
    /// Значения, которые могут быть установлены/получены для цифровых портов в режимах INPUT/OUTPUT.
    /// </summary>
    public enum PinDigitalValue : int
    {
        Low = 0,
        High = 1
    }

    ///// <summary>
    ///// Значения, которые могут быть установлены/получены для цифровых портов в режиме PWM.
    ///// </summary>
    //public class PinAnalogValue : int
    //{

    //}

    /// <summary>
    /// Сообщения, которые могут быть отправлены/получены по протоколу Firmata.
    /// </summary>
    [Flags]
    public enum Messages : int
    {
        // send data for a digital port 
        DIGITAL_MESSAGE = 0x90,
        // send data for an analog _pin (or PWM) 
        ANALOG_MESSAGE = 0xE0,
        // enable analog input by _pin
        REPORT_ANALOG = 0xC0,
        // enable digital input by port 
        REPORT_DIGITAL = 0xD0,
        // set a _pin to INPUT/OUTPUT/PWM/etc 
        SET_PIN_MODE = 0xF4,
        // report firmware version 
        REPORT_VERSION = 0xF9,
        // reset from MIDI 
        SYSTEM_RESET = 0xFF,
        // start a MIDI SysEx message 
        START_SYSEX = 0xF0,
        // end a MIDI SysEx message 
        END_SYSEX = 0xF7,
        // report name and version of the firmware
        REPORT_FIRMWARE = 0x79,

        // extended commands
        // receive a string
        STRING_DATA = 0x71,

        // ask for pin's current report mode
        PIN_REPORT_QUERY = 0x01,
        // reply with pin's current report mode
        PIN_REPORT_RESPONSE = 0x02,


        FIRMATA_STRING = 0x71,

        // ask for current and supported _pin modes
        PIN_MODE_QUERY = 0x72,
        // reply with current and supported _pin modes
        PIN_MODE_RESPONSE = 0x73,
        PIN_STATE_QUERY = 0x6D,
        PIN_STATE_RESPONSE = 0x6E,
        CAPABILITY_QUERY = 0x6B,
        CAPABILITY_RESPONSE = 0x6C,
        ANALOG_MAPPING_QUERY = 0x69,
        ANALOG_MAPPING_RESPONSE = 0x6A,
    }

    /// <summary>
    /// Остальные константы Firmata-протокола.
    /// </summary>
    [Flags]
    public enum Other : int
    {
        MODE_INPUT = 0x00,
        MODE_OUTPUT = 0x01,
        MODE_ANALOG = 0x02,
        MODE_PWM = 0x03,
        MODE_SERVO = 0x04,
        MODE_SHIFT = 0x05,
        MODE_I2C = 0x06,
    }

    /// <summary>
    /// Перечисление портов микроконтроллера Arduino.
    /// </summary>
    public enum Pins : int
    {
        None = 0,

        D1 = 1,
        D2 = 2,
        D3 = 3,
        D4 = 4,
        D5 = 5,
        D6 = 6,
        D7 = 7,
        D8 = 8,
        D9 = 9,
        D10 = 10,
        D11 = 11,
        D12 = 12,
        D13 = 13,

        A0 = 16,
        A1 = 17,
        A2 = 18,
        A3 = 19,
        A4 = 20,
        A5 = 21

    }
    #endregion

    #region Is
    public class Types
    {
        public static bool IsPinAnalog(Pins pin)
        {
            if ((int)pin >= (int)Pins.A0 && (int)pin <= (int)Pins.A5) return true;
            return false;
        }
        public static bool IsPinDigital(Pins pin)
        {
            if ((int)pin >= (int)Pins.D1 && (int)pin <= (int)Pins.D13) return true;
            return false;
        }

        public static Pins AnalogPinToTotal(int pin)
        {
            try
            {
                return (Pins)(pin + 16);
            }
            catch (Exception)
            {

            }
            return Pins.None;
        }
    }
    #endregion
}
